package com.videoaggre.zcl.helper.player.cover

import android.app.Activity
import android.content.Context
import android.media.AudioManager
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.MotionEvent
import android.view.View
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import com.kk.taurus.playerbase.event.BundlePool
import com.kk.taurus.playerbase.event.EventKey
import com.kk.taurus.playerbase.event.OnPlayerEventListener
import com.kk.taurus.playerbase.receiver.BaseCover
import com.kk.taurus.playerbase.receiver.IReceiverGroup.OnGroupValueUpdateListener
import com.kk.taurus.playerbase.touch.OnTouchGestureListener
import com.kk.taurus.playerbase.touch.TouchEventIndicator
import com.kk.taurus.playerbase.utils.TimeUtil
import com.videoaggre.zcl.R
import com.videoaggre.zcl.helper.player.DataInter

class GestureCover(context: Context?) : BaseCover(context), OnTouchGestureListener, TouchEventIndicator {
    private val mVolumeBox: View by lazy { view.findViewById(R.id.cover_player_gesture_operation_volume_box) }
    private val mBrightnessBox: View by lazy { view.findViewById(R.id.cover_player_gesture_operation_brightness_box) }
    private val mVolumeIcon: ImageView by lazy { view.findViewById(R.id.cover_player_gesture_operation_volume_icon) }
    private val mVolumeText: TextView by lazy { view.findViewById(R.id.cover_player_gesture_operation_volume_text) }
    private val mBrightnessText: TextView by lazy { view.findViewById(R.id.cover_player_gesture_operation_brightness_text) }
    private val mFastForwardBox: View by lazy { view.findViewById(R.id.cover_player_gesture_operation_fast_forward_box) }
    private val mFastForwardStepTime: TextView by lazy { view.findViewById(R.id.cover_player_gesture_operation_fast_forward_text_view_step_time) }
    private val mFastForwardProgressTime: TextView by lazy { view.findViewById(R.id.cover_player_gesture_operation_fast_forward_text_view_progress_time) }
    private var firstTouch = false
    private var mSeekProgress = -1
    private var mWidth = 0
    private var mHeight = 0
    private var newPosition: Long = 0
    private var mHorizontalSlide = false
    private var brightness = -1f
    private var volume = 0
    private var audioManager: AudioManager? = null
    private var mMaxVolume = 0
    private var mGestureEnable = true
    private val mBundle: Bundle by lazy { Bundle() }
    private var mGestureHorizontalEnable = true
    private val mHandler: Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            when (msg.what) {
            }
        }
    }
    private var horizontalSlide = false
    private var rightVerticalSlide = false
    override fun onReceiverBind() {
        super.onReceiverBind()
        initAudioManager(context)
    }

    private fun initAudioManager(context: Context) {
        audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
        mMaxVolume = audioManager!!.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
    }

    private fun sendSeekEvent(progress: Int) {
        if (!mGestureHorizontalEnable) return
        groupValue.putBoolean(DataInter.Key.KEY_TIMER_UPDATE_ENABLE, false)
        mSeekProgress = progress
        mHandler.removeCallbacks(mSeekEventRunnable)
        mHandler.postDelayed(mSeekEventRunnable, 300)
    }

    private val mSeekEventRunnable = Runnable {
        if (mSeekProgress < 0) return@Runnable
        val bundle = BundlePool.obtain()
        bundle.putInt(EventKey.INT_DATA, mSeekProgress)
        requestSeek(bundle)
    }
    private val mOnGroupValueUpdateListener: OnGroupValueUpdateListener = object : OnGroupValueUpdateListener {
        override fun filterKeys(): Array<String> {
            return arrayOf(
                DataInter.Key.KEY_COMPLETE_SHOW,
                DataInter.Key.KEY_IS_LANDSCAPE,
                DataInter.Key.KEY_CONTROLLER_TOP_ENABLE,
            )
        }

        override fun onValueUpdate(key: String, value: Any) {
            if (DataInter.Key.KEY_COMPLETE_SHOW == key) {
                setGestureEnable(!(value as Boolean))
            } else if (DataInter.Key.KEY_IS_LANDSCAPE == key) {
                notifyWH()
            } else if (DataInter.Key.KEY_CONTROLLER_TOP_ENABLE == key) {
                mGestureHorizontalEnable = value as Boolean
            }
        }
    }

    override fun onCoverAttachedToWindow() {
        super.onCoverAttachedToWindow()
        mGestureHorizontalEnable = groupValue.getBoolean(DataInter.Key.KEY_GESTURE_HORIZONTAL_ENABLE, mGestureHorizontalEnable)
        groupValue.registerOnGroupValueUpdateListener(mOnGroupValueUpdateListener)
        notifyWH()
    }

    private fun notifyWH() {
        view.viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                mWidth = view.width
                mHeight = view.height
                view.viewTreeObserver.removeOnGlobalLayoutListener(this)
            }
        })
    }

    override fun onCoverDetachedToWindow() {
        super.onCoverDetachedToWindow()
        groupValue.unregisterOnGroupValueUpdateListener(mOnGroupValueUpdateListener)
    }

    private fun setVolumeBoxState(state: Boolean) {
        mVolumeBox.visibility = if (state) View.VISIBLE else View.GONE
    }

    private fun setVolumeIcon(resId: Int) {
        mVolumeIcon.setImageResource(resId)
    }

    private fun setVolumeText(text: String?) {
        mVolumeText.text = text
    }

    private fun setBrightnessBoxState(state: Boolean) {
        mBrightnessBox.visibility = if (state) View.VISIBLE else View.GONE

    }

    private fun setBrightnessText(text: String?) {
        mBrightnessText.text = text

    }

    private fun setFastForwardState(state: Boolean) {
        mFastForwardBox.visibility = if (state) View.VISIBLE else View.GONE
    }

    private fun setFastForwardStepTime(text: String) {
        mFastForwardStepTime.text = text
    }

    private fun setFastForwardProgressTime(text: String) {
        mFastForwardProgressTime.text = text
    }

    fun setGestureEnable(gestureEnable: Boolean) {
        mGestureEnable = gestureEnable
    }

    public override fun onCreateCoverView(context: Context): View {
        return View.inflate(context, R.layout.view_cover_gesture, null)
    }

    override fun getCoverLevel(): Int {
        return levelLow(0)
    }

    override fun onPlayerEvent(eventCode: Int, bundle: Bundle?) {
        when (eventCode) {
            OnPlayerEventListener.PLAYER_EVENT_ON_VIDEO_RENDER_START -> setGestureEnable(true)
        }
    }

    override fun onErrorEvent(eventCode: Int, bundle: Bundle?) {}
    override fun onReceiverEvent(eventCode: Int, bundle: Bundle?) {}
    override fun onSingleTapConfirmed(event: MotionEvent) {}
    override fun onLongPress(event: MotionEvent) {
        Toast.makeText(context, "onLongPress", Toast.LENGTH_SHORT).show()
    }

    override fun onDoubleTap(event: MotionEvent) {}
    override fun onDown(event: MotionEvent) {
        mHorizontalSlide = false
        firstTouch = true
        volume = getVolume()
    }

    override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float) {
        if (!mGestureEnable) return
        val mOldX = e1.x
        val mOldY = e1.y
        val deltaY = mOldY - e2.y
        val deltaX = mOldX - e2.x
        if (firstTouch) {
            horizontalSlide = Math.abs(distanceX) >= Math.abs(distanceY)
            rightVerticalSlide = mOldX > mWidth * 0.5f
            firstTouch = false
        }
        if (horizontalSlide) {
            onHorizontalSlide(-deltaX / mWidth)
        } else {
            if (Math.abs(deltaY) > mHeight) return
            if (rightVerticalSlide) {
                onRightVerticalSlide(deltaY / mHeight)
            } else {
                onLeftVerticalSlide(deltaY / mHeight)
            }
        }
    }

    private val duration: Int
        get() {
            val playerStateGetter = playerStateGetter
            return playerStateGetter?.duration ?: 0
        }
    private val currentPosition: Int
        get() {
            val playerStateGetter = playerStateGetter
            return playerStateGetter?.currentPosition ?: 0
        }

    private fun onHorizontalSlide(percent: Float) {
        if (!mGestureHorizontalEnable) return
        if (duration <= 0) return
        mHorizontalSlide = true
        if (groupValue.getBoolean(DataInter.Key.KEY_TIMER_UPDATE_ENABLE)) {
            groupValue.putBoolean(DataInter.Key.KEY_TIMER_UPDATE_ENABLE, false)
        }
        val position = currentPosition.toLong()
        val duration = duration.toLong()
        val deltaMax = Math.min(duration / 2.toLong(), duration - position)
        var delta = (deltaMax * percent).toLong()
        newPosition = delta + position
        if (newPosition > duration) {
            newPosition = duration
        } else if (newPosition <= 0) {
            newPosition = 0
            delta = -position
        }
        val showDelta = delta.toInt() / 1000
        if (showDelta != 0) {
            mBundle.putInt(EventKey.INT_ARG1, newPosition.toInt())
            mBundle.putInt(EventKey.INT_ARG2, duration.toInt())
            notifyReceiverPrivateEvent(DataInter.ReceiverKey.KEY_CONTROLLER_COVER, DataInter.PrivateEvent.EVENT_CODE_UPDATE_SEEK, mBundle)
            setFastForwardState(true)
            val text = if (showDelta > 0) "+$showDelta" else "" + showDelta
            setFastForwardStepTime(text + "s")
            val progressText = TimeUtil.getTimeSmartFormat(newPosition) + "/" + TimeUtil.getTimeSmartFormat(duration)
            setFastForwardProgressTime(progressText)
        }
    }

    private fun onRightVerticalSlide(percent: Float) {
        mHorizontalSlide = false
        var index = (percent * mMaxVolume).toInt() + volume
        if (index > mMaxVolume) index = mMaxVolume else if (index < 0) index = 0
        // 变更声音
        audioManager!!.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0)
        // 变更进度条
        val i = (index * 1.0 / mMaxVolume * 100).toInt()
        var s = "$i%"
        if (i == 0) {
            s = "OFF"
        }
        // 显示
        setVolumeIcon(if (i == 0) R.mipmap.ic_volume_off_white else R.mipmap.ic_volume_up_white)
        setBrightnessBoxState(false)
        setFastForwardState(false)
        setVolumeBoxState(true)
        setVolumeText(s)
    }

    private fun onLeftVerticalSlide(percent: Float) {
        mHorizontalSlide = false
        val activity = activity ?: return
        if (brightness < 0) {
            brightness = activity.window.attributes.screenBrightness
            if (brightness <= 0.00f) {
                brightness = 0.50f
            } else if (brightness < 0.01f) {
                brightness = 0.01f
            }
        }
        setVolumeBoxState(false)
        setFastForwardState(false)
        setBrightnessBoxState(true)
        val lpa = activity.window.attributes
        lpa.screenBrightness = brightness + percent
        if (lpa.screenBrightness > 1.0f) {
            lpa.screenBrightness = 1.0f
        } else if (lpa.screenBrightness < 0.01f) {
            lpa.screenBrightness = 0.01f
        }
        setBrightnessText((lpa.screenBrightness * 100).toInt().toString() + "%")
        activity.window.attributes = lpa
    }

    private val activity: Activity?
        get() {
            val context = context
            return if (context is Activity) {
                context
            } else null
        }

    private fun getVolume(): Int {
        volume = audioManager!!.getStreamVolume(AudioManager.STREAM_MUSIC)
        if (volume < 0) volume = 0
        return volume
    }

    override fun onEndGesture() {
        volume = -1
        brightness = -1f
        setVolumeBoxState(false)
        setBrightnessBoxState(false)
        setFastForwardState(false)
        if (newPosition >= 0 && mHorizontalSlide) {
            sendSeekEvent(newPosition.toInt())
            newPosition = 0
        } else {
            groupValue.putBoolean(DataInter.Key.KEY_TIMER_UPDATE_ENABLE, true)
        }
        mHorizontalSlide = false
    }

    override fun disallowReceiveTouchEvent(): Boolean {
        return groupValue.getBoolean(DataInter.Key.KEY_ERROR_SHOW, false)
    }
}